﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace NazTek.Extension.Clr4.Test
{
    /// <summary>
    /// Contains Unit Tests for StringExtension class public members
    /// </summary>
    [TestClass()]
    public class StringExtensionTest
    {
        private TestContext testContextInstance;

        /// <summary>
        /// Gets/Sets current test context, e.g., property bag
        /// </summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        /// <summary>
        /// Attempts to use ToEnum to convert a string to a class, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_FromClass()
        {
            MockData.DEFAULT_GENDER.ToString().ToEnum<MockPerson>();
        }
        /// <summary>
        /// Attempts to use ToEnum to convert an empty string to an enumerated value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_EmptyString()
        {
            "".ToEnum<MockGender>();
        }
        /// <summary>
        /// Attempts to use ToEnum to convert a string, which has no corresponding enumerated value, to an enumerated value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_Undefined()
        {
            StringResource.Default.Data_Default_Null_Override.ToEnum<MockGender>();
        }
        /// <summary>
        /// Attempts to use ToEnum to convert an int, which has no corresponding enumerated value, to an enumerated value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_UndefinedInt()
        {
            5.ToString().ToEnum<MockGender>();
        }
        /// <summary>
        /// Attempts to use ToEnum to convert an int, which has a corresponding enumerated value, to an enumerated value, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_DefinedInt()
        {
            Assert.AreEqual<Enum>(MockGender.Female, Convert.ToInt32(MockGender.Female).ToString().ToEnum<MockGender>());
        }
        /// <summary>
        /// Attempts to use ToEnum to convert a byte, which has no corresponding enumerated value, to an enumerated value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_UndefinedByte()
        {
            Convert.ToByte(5).ToString().ToEnum<MockSalutation>();
        }
        /// <summary>
        /// Attempts to use ToEnum to convert a byte, which has corresponding enumerated value, to an enumerated value, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_DefinedByte()
        {
            Assert.AreEqual<MockSalutation>(MockSalutation.Mrs, Convert.ToByte(MockSalutation.Mrs).ToString().ToEnum<MockSalutation>());
        }
        /// <summary>
        /// Attempts to use ToEnum to convert a short, which has no corresponding enumerated value, to an enumerated value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_UndefinedShort()
        {
            Convert.ToInt16(10).ToString().ToEnum<MockAgeGroup>();
        }
        /// <summary>
        /// Attempts to use ToEnum, with exception, to convert a string with corresponding enum value to an enum value with underlying int type, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_DefinedIntString()
        {
            Assert.AreEqual<Enum>(MockGender.Male, MockGender.Male.ToString().ToEnum<MockGender>());
        }
        /// <summary>
        /// Attempts to use ToEnum, with exception, to convert a string with corresponding enum value to an enum value with underlying short type, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_DefinedShortString()
        {
            Assert.AreEqual<Enum>(MockAgeGroup.MiddleAged, MockAgeGroup.MiddleAged.ToString().ToEnum<MockAgeGroup>());
        }
        /// <summary>
        /// Attempts to use ToEnum, with exception, to convert a string with corresponding enum value to an enum value with underlying byte type, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_DefinedByteString()
        {
            Assert.AreEqual<Enum>(MockSalutation.Mr, MockSalutation.Mr.ToString().ToEnum<MockSalutation>());
        }
        /// <summary>
        /// Attempts to use ToEnumFromAttributeValue to identify an enum value from a specified keyless additional info attribute value, should return corresponding enum value
        /// </summary>
        [TestMethod()]
        public void TestToEnum_FromDefinedDescripion()
        {
            Assert.AreEqual<Enum>(MockGender.Female, MockData.ENUM_ATTRIBUTE_FEMALE_VALUE.ToEnumFromDescription<MockGender>());
        }
        /// <summary>
        /// Attempts to use ToEnumFromAttributeValue to identify an enum value from a specified non-existent keyless additional info attribute value, should return null
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(CustomException))]
        public void TestToEnum_FromUndefinedDescripion()
        {
            "G".ToEnumFromDescription<MockGender>();
        }
        /// <summary>
        /// Converts a base 32 binary string to its corresponding type instance
        /// </summary>
        [TestMethod()]
        public void TestToType_Base32Binary()
        {
            Assert.IsTrue(MockData.SERIAL_BASE32_BINARY_MOCK_PERSON.ToType<MockPerson>(FormatOption.Base32Binary).Equals(new MockPerson()));
        }
        /// <summary>
        /// Converts a base 32 soap string to its corresponding type instance
        /// </summary>
        [TestMethod()]
        public void TestToType_Base32Soap()
        {
            Assert.IsTrue(MockData.SERIAL_BASE32_SOAP_MOCK_PERSON.ToType<MockPerson>(FormatOption.Base32Soap).Equals(new MockPerson()));
        }
        /// <summary>
        /// Converts a base 64 binary string to its corresponding type instance
        /// </summary>
        [TestMethod()]
        public void TestToType_Base64Binary()
        {
            Assert.IsTrue(MockData.SERIAL_BASE64_BINARY_MOCK_PERSON.ToType<MockPerson>(FormatOption.Base64Binary).Equals(new MockPerson()));
        }
        /// <summary>
        /// Converts a base 64 soap string to its corresponding type instance
        /// </summary>
        [TestMethod()]
        public void TestToType_Base64Soap()
        {
            Assert.IsTrue(MockData.SERIAL_BASE64_SOAP_MOCK_PERSON.ToType<MockPerson>(FormatOption.Base64Soap).Equals(new MockPerson()));
        }
        /// <summary>
        /// Tests pox deserialization
        ///</summary>
        [TestMethod()]
        public void TestToType_Pox()
        {
            MockPerson expected = new MockPerson();
            MockPerson actual = MockData.SERIAL_POX_MOCK_PERSON.ToType<MockPerson>(FormatOption.Pox);
            Assert.IsTrue(actual.Equals(expected));
        }
        /// <summary>
        ///A test for Decompress
        ///</summary>
        [TestMethod()]
        public void TestDecompress()
        {
            string actual = MockData.SERIAL_BASE32_BINARY_MOCK_PERSON_COMPRESSED.Decompress();
            Assert.IsTrue(MockData.SERIAL_BASE32_BINARY_MOCK_PERSON.Equals(actual));
        }
        /// <summary>
        ///A test for Compress
        ///</summary>
        [TestMethod()]
        public void TestCompress()
        {
            string actual = MockData.SERIAL_BASE32_BINARY_MOCK_PERSON.Compress();
            Assert.IsTrue(MockData.SERIAL_BASE32_BINARY_MOCK_PERSON_COMPRESSED.Equals(actual));
        }
        /// <summary>
        /// A test for hash randomness
        /// </summary>
        [TestMethod()]
        public void TestGetHashValue_RandomSalt()
        {
            string text = MockData.SERIAL_BASE32_SOAP_MOCK_PERSON;
            string actual1 = text.GetHashValue();
            string actual2 = text.GetHashValue();
            Assert.AreNotEqual<string>(actual1, actual2);
        }

        [TestMethod()]
        public void TestGetHashValue_EmptySalt()
        {
            string text = MockData.SERIAL_BASE32_SOAP_MOCK_PERSON;
            byte[] salt = new byte[] { };
            string expected = MockData.SERIAL_BASE32_SOAP_MOCK_PERSON_NO_SALT_HASH;
            string actual1 = text.GetHashValue(salt: salt);
            string actual2 = text.GetHashValue(salt: salt);
            Assert.AreEqual<string>(expected, actual1);
            Assert.AreEqual<string>(expected, actual2);
        }

        [TestMethod()]
        public void TestGetHashValue_FixedSalt()
        {
            string text = MockData.SERIAL_BASE32_SOAP_MOCK_PERSON;
            byte[] salt = Common.RandomSalt;
            string actual1 = text.GetHashValue(salt: salt);
            string actual2 = text.GetHashValue(salt: salt);
            Assert.AreEqual<string>(actual1, actual1);
        }
    }
}